package com.mxpio.erp.asset.service.impl;

import com.alibaba.excel.EasyExcel;
import com.mxpio.erp.asset.purchase.entity.InitializeReceivingNoticeImportModel;
import com.mxpio.erp.asset.purchase.entity.ReceivingNoticeImportModel;
import com.mxpio.erp.asset.service.CommonUploadService;
import com.mxpio.erp.asset.utils.excel.NoticeExcelListener;
import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.inventory.entity.Warehouse;
import com.mxpio.erp.common.purchase.entity.ReceivingNotice;
import com.mxpio.erp.common.purchase.entity.ReceivingNoticeLine;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.workshop.entity.MoPickingNotice;
import com.mxpio.erp.common.workshop.entity.MoPickingNoticeLine;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.jpa.JpaUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author : 吴盼盼
 * @Datetime : 2022/10/14 11:35
 * @Desc :
 * @Modor :  Modifytime:
 * @modDesc :
 */
@Service
public class CommonUploadServiceImpl implements CommonUploadService {
    @Override
    @Transactional
    public List<ReceivingNoticeImportModel> uploadReceivingnotice(InputStream inputStream) {
        NoticeExcelListener<ReceivingNoticeImportModel> excelListener = new NoticeExcelListener<>();
        EasyExcel.read(inputStream,ReceivingNoticeImportModel.class,excelListener).sheet().doRead();
        List<ReceivingNoticeImportModel> modelList = excelListener.getList();

        int size = modelList == null ? 0 : modelList.size();
        if (size==0){
            throw new MBootException("上传文件的不能为空或Excle数据都不正确");
        }
        if (size > 10000) {
            throw new MBootException("上传的文件不能超过1万条数据");
        }

        List<String> whCodeList = new ArrayList<>();
        List<String> itemCodeList = new ArrayList<>();
        modelList.forEach(m -> {
            whCodeList.add(m.getWhCode());
            itemCodeList.add(m.getItemCode());
        });
        List<Warehouse> warehouseList =  JpaUtil.linq(Warehouse.class).in("whCode", whCodeList).list();
        Map<String, Warehouse> warehouseMap = JpaUtil.index(warehouseList,"whCode");//查询仓库
        List<Item> itemList = JpaUtil.linq(Item.class).in("itemCode", itemCodeList).list();
        Map<String, Item> itemMap = JpaUtil.index(itemList,"itemCode");//查询物料
        Set<String> rowIdSet = new HashSet<>();
        List<ReceivingNoticeImportModel> succImportModelList = new ArrayList<>();
        for (int i = 0; i < modelList.size(); i++) {
            ReceivingNoticeImportModel model = modelList.get(i);
            if (StringUtils.isBlank(model.getWhCode())){
                model.fail("仓库编码为空");
                continue;
            }
            if (StringUtils.isBlank(model.getItemCode())){
                model.fail("物资编码为空");
                continue;
            }
            if (model.getQuantity()==null||model.getQuantity().compareTo(BigDecimal.ZERO)==0){
                model.fail("数量不能为空或为零");
                continue;
            }
            boolean flag = true;
            StringBuffer sb = new StringBuffer();
            String whCode = model.getWhCode();
            String itemCode = model.getItemCode();
            String rowIdStr = whCode+"_"+itemCode;
            if (!warehouseMap.containsKey(whCode)){
                flag = false;
                sb.append("仓库编码不存在;");
            }
            if (!itemMap.containsKey(itemCode)){
                flag = false;
                sb.append("物资编码不存在;");
            }
            if (rowIdSet.contains(rowIdStr)){
                flag = false;
                sb.append("存在仓库和物料相同的其他行数据;");
            }else{
                rowIdSet.add(rowIdStr);
            }
            if (flag) {
                model.setImportSuccess("成功");
                model.setImportMsg("导入成功");
            } else {
                model.setImportSuccess("失败");
                model.setImportMsg(sb.toString());
                continue;
            }
            succImportModelList.add(model);
        }
        //处理验证通过数据
        if (succImportModelList.size()>0){
            Map<String, List<ReceivingNoticeImportModel>> map = succImportModelList.stream().collect(Collectors.groupingBy(ReceivingNoticeImportModel::getWhCode));
            for (String whCode: map.keySet()){//根据仓库维度 生成对应的仓单
                List<ReceivingNoticeImportModel> submodelList = map.get(whCode);
                ReceivingNotice receivingNotice = new ReceivingNotice();
                receivingNotice.setNoticeDate(new Date());
                receivingNotice.setWhCode(whCode);
                receivingNotice.setAccessType(OrderEnums.AccessType.IN.getCode());
                receivingNotice.setPickingType(NoticeStatusEnums.NoticeType.PO_IN.getCode());
                receivingNotice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.DRAFT.getStatusCode());//默认草稿
                JpaUtil.save(receivingNotice);
                List<ReceivingNoticeLine> lineList = new ArrayList<>();
                int lineNo = 0;
                for (ReceivingNoticeImportModel per:submodelList){
                    ReceivingNoticeLine line = new ReceivingNoticeLine();
                    lineNo++;
                    line.setNoticeNo(receivingNotice.getNoticeNo());
                    line.setLineNo(lineNo+"");
                    Item item = JpaUtil.linq(Item.class).idEqual(per.getItemCode()).findOne();
                    line.setItemName(item.getItemName());
                    line.setItemSpec(item.getItemSpec());
                    line.setUnitCode(item.getUnitCode());
                    line.setQuantity(per.getQuantity());
                    line.setItemCode(per.getItemCode());
                    line.setMemo(per.getNote());
                    lineList.add(line);
                }
                if (lineList.size()>0){
                    JpaUtil.save(lineList);
                }
            }
        }
        return modelList;
    }



    @Override
    @Transactional
    public List<InitializeReceivingNoticeImportModel> uploadInitializeReceivingnotice(InputStream inputStream) {
        NoticeExcelListener<InitializeReceivingNoticeImportModel> excelListener = new NoticeExcelListener<>();
        EasyExcel.read(inputStream,InitializeReceivingNoticeImportModel.class,excelListener).sheet().doRead();
        List<InitializeReceivingNoticeImportModel> modelList = excelListener.getList();

        int size = modelList == null ? 0 : modelList.size();
        if (size==0){
            throw new MBootException("上传文件的不能为空或Excle数据都不正确");
        }
        if (size > 10000) {
            throw new MBootException("上传的文件不能超过1万条数据");
        }

        List<String> whCodeList = new ArrayList<>();
        List<String> itemCodeList = new ArrayList<>();
        modelList.forEach(m -> {
            whCodeList.add(m.getWhCode());
            itemCodeList.add(m.getItemCode());
        });
        List<Warehouse> warehouseList =  JpaUtil.linq(Warehouse.class).in("whCode", whCodeList).list();
        Map<String, Warehouse> warehouseMap = JpaUtil.index(warehouseList,"whCode");//查询仓库
        List<Item> itemList = JpaUtil.linq(Item.class).in("itemCode", itemCodeList).list();
        Map<String, Item> itemMap = JpaUtil.index(itemList,"itemCode");//查询物料
        Set<String> rowIdSet = new HashSet<>();
        List<InitializeReceivingNoticeImportModel> succImportModelList = new ArrayList<>();
        for (int i = 0; i < modelList.size(); i++) {
            InitializeReceivingNoticeImportModel model = modelList.get(i);
            if (StringUtils.isBlank(model.getWhCode())){
                model.fail("仓库编码为空");
                continue;
            }
            if (StringUtils.isBlank(model.getItemCode())){
                model.fail("物资编码为空");
                continue;
            }
            if (StringUtils.isBlank(model.getLotNo())){
                model.fail("物资批次为空");
                continue;
            }
            if (model.getQuantity()==null||model.getQuantity().compareTo(BigDecimal.ZERO)==0){
                model.fail("数量不能为空或为零");
                continue;
            }
            boolean flag = true;
            StringBuffer sb = new StringBuffer();
            String whCode = model.getWhCode();
            String itemCode = model.getItemCode();
            String lotNo = model.getLotNo();
            String rowIdStr = whCode+"_"+itemCode+"_"+lotNo;
            if (!warehouseMap.containsKey(whCode)){
                flag = false;
                sb.append("仓库编码不存在;");
            }
            if (!itemMap.containsKey(itemCode)){
                flag = false;
                sb.append("物资编码不存在;");
            }
            if (rowIdSet.contains(rowIdStr)){
                flag = false;
                sb.append("存在仓库和物料批次相同的其他行数据;");
            }else{
                rowIdSet.add(rowIdStr);
            }
            if (flag) {
                model.setImportSuccess("成功");
                model.setImportMsg("导入成功");
            } else {
                model.setImportSuccess("失败");
                model.setImportMsg(sb.toString());
                continue;
            }
            succImportModelList.add(model);
        }
        //处理验证通过数据
        if (succImportModelList.size()>0){
            Map<String, List<InitializeReceivingNoticeImportModel>> map = succImportModelList.stream().collect(Collectors.groupingBy(InitializeReceivingNoticeImportModel::getWhCode));
            for (String whCode: map.keySet()){//根据仓库维度 生成对应的仓单
                List<InitializeReceivingNoticeImportModel> submodelList = map.get(whCode);
                MoPickingNotice receivingNotice = new MoPickingNotice();
                receivingNotice.setNoticeDate(new Date());
                receivingNotice.setWhCode(whCode);
                receivingNotice.setAccessType(OrderEnums.AccessType.IN.getCode());
                receivingNotice.setPickingType(NoticeStatusEnums.NoticeType.INIT_IN.getCode());//初始入库
                receivingNotice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.CREATE.getStatusCode());//默认开立
                JpaUtil.save(receivingNotice);
                List<MoPickingNoticeLine> lineList = new ArrayList<>();
                int lineNo = 0;
                for (InitializeReceivingNoticeImportModel per:submodelList){
                    MoPickingNoticeLine line = new MoPickingNoticeLine();
                    lineNo++;
                    line.setNoticeNo(receivingNotice.getNoticeNo());
                    line.setLineNo(lineNo+"");
                    Item item = JpaUtil.linq(Item.class).idEqual(per.getItemCode()).findOne();
                    line.setItemName(item.getItemName());
                    line.setItemSpec(item.getItemSpec());
                    line.setUnitCode(item.getUnitCode());
                    line.setQuantity(per.getQuantity());
                    line.setItemCode(per.getItemCode());
                    line.setMemo(per.getNote());
                    line.setLotNo(per.getLotNo());//指定批次
                    lineList.add(line);
                }
                if (lineList.size()>0){
                    JpaUtil.save(lineList);
                }
            }
        }
        return modelList;
    }
    /*public static void main(String[] agrs){//测试
        NoticeExcelListener<ReceivingNoticeImportModel> excelListener = new NoticeExcelListener<>();
        File file = new File("C:\\Users\\wupaa\\Desktop\\inpt.xlsx");
        byte[] bytes = file2byte(file);
        EasyExcel.read(new ByteArrayInputStream(bytes),ReceivingNoticeImportModel.class,excelListener).sheet().doRead();
        List<ReceivingNoticeImportModel> modelList = excelListener.getList();
    }

    public static byte[] file2byte(File file) {
        if (file == null) {
            return null;
        }
        FileInputStream fileInputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fileInputStream.read(b)) != -1) {
                byteArrayOutputStream.write(b, 0 , n);
            }
            return byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (byteArrayOutputStream != null) {
                    byteArrayOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }*/

}
